package bbcom.interfaces;

import bbcom.*;

import java.util.List;
import java.util.Map;

/**
 * Created by Thanh-Trung Pham.
 */
public interface IContainer {

    /**
     * Set the configuration settings.
     *
     * @param systemName                     the system name.
     * @param deviceContainerType            the current device container type.
     * @param baseFolderName                 the base folder's name (used to find dependencies (jar files, class folders).
     * @param allDeviceContainersIPAddresses all device containers' IP addresses (used to check whether the whole deployment has completed and to build up the cluster of containers)
     * @throws Exception if there is an error.
     */
    void setConfigurationSettings(String systemName, DeviceContainerType deviceContainerType, Map<String, String> allDeviceContainersIPAddresses, String baseFolderName) throws Exception;

    /**
     * Set the plugins.
     * @param implementationParserPlugin the implementation parser plugin.
     * @param userInterfaceParserPlugin  the user interface parser plugin.
     * @param propertiesParserPlugin     the properties parser plugin.
     * @throws Exception if there is an error.
     */
    void setPlugins(IImplementationParser implementationParserPlugin, IUserInterfaceParser userInterfaceParserPlugin, IPropertiesParser propertiesParserPlugin) throws Exception;

    /**
     * Load the given dependencies (e.g. jar files).
     *
     * @param dependencies the given dependencies.
     * @throws Exception if there is an error.
     */
    void loadDependencies(List<String> dependencies) throws Exception;

    /**
     * Create a component instance of the given component instance type.
     *
     * @param componentInstanceType the given component instance type.
     * @throws Exception if there is an error.
     */
    void createComponentInstance(ComponentInstanceType componentInstanceType) throws Exception;

    /**
     * Create an event channel of the given event channel type.
     *
     * @param eventChannelType the given event channel type.
     * @throws Exception
     */
    void createEventChannel(EventChannelType eventChannelType) throws Exception;

    /**
     * Register the given interface types.
     *
     * @param interfaceTypes the given interface types.
     */
    void registerInterfaces(List<InterfaceType> interfaceTypes);

    /**
     * Register the given event group types.
     *
     * @param eventGroupTypes the given event group types.
     */
    void registerEventGroups(List<EventGroupType> eventGroupTypes);

    /**
     * Register the given primitive component types.
     *
     * @param primitiveComponentTypes the given primitive component types.
     */
    void registerComponents(List<PrimitiveComponentType> primitiveComponentTypes);


    /**
     * Create a connector.
     *
     * @param requiredComponentInstanceName                  the name of the required component instance.
     * @param requiredRoleName                               the required role name.
     * @param interfaceName                                  the interface name.
     * @param providedComponentInstanceName                  the name of the provided component instance.
     * @param deviceContainerNameOfProvidedComponentInstance the name of the device container of the provided component instance.
     * @throws Exception if there is an error.
     */
    void createConnector(String requiredComponentInstanceName, String requiredRoleName, String interfaceName, String providedComponentInstanceName, String deviceContainerNameOfProvidedComponentInstance) throws Exception;

    /**
     * Create an event connector.
     *
     * @param sourceComponentInstanceName                the name of the source component instance.
     * @param sourceRoleName                             the source role name
     * @param eventGroupName                             the event group name.
     * @param sinkComponentInstanceName                  the name of the sink component instance.
     * @param deviceContainerNameOfSinkComponentInstance the name of the device container of the sink component instance.
     * @throws Exception if there is an error.
     */
    void createEventConnector(String sourceComponentInstanceName, String sourceRoleName, String eventGroupName, String sinkComponentInstanceName, String deviceContainerNameOfSinkComponentInstance) throws Exception;

    /**
     * Create a channel source connector.
     *
     * @param sourceComponentInstanceName       the name of the source component instance.
     * @param sourceRoleName                    the source role name.
     * @param eventGroupName                    the event group name.
     * @param eventChannelName                  the event channel name.
     * @param deviceContainerNameOfEventChannel the name of the device container of the event channel.
     * @throws Exception if there is an error.
     */
    void createChannelSourceConnector(String sourceComponentInstanceName, String sourceRoleName, String eventGroupName, String eventChannelName, String deviceContainerNameOfEventChannel) throws Exception;

    /**
     * Create a channel sink connector.
     *
     * @param eventChannelName                           the event channel name.
     * @param sinkComponentInstanceName                  the sink component instance name.
     * @param deviceContainerNameOfSinkComponentInstance the name of the device container of the sink component instance.
     * @param filterRule                                 the filter rule.
     * @throws Exception if there is an error.
     */
    void createChannelSinkConnector(String eventChannelName, String sinkComponentInstanceName, String deviceContainerNameOfSinkComponentInstance, FilterRuleType filterRule) throws Exception;

    /**
     * Inform the local deployment completion.
     */
    void informLocalDeploymentCompletion();

    /**
     * Create a user interface for a system-level provided role.
     *
     * @param systemLevelProvidedRoleName         the system-level provided role name.
     * @param interfaceName                       the interface name.
     * @param providedComponentInstanceName       the provided component instance name.
     * @param providedRoleNameOfComponentInstance the provided role name of the component instance.
     * @param userInterfaceType                   the given user interface type.
     * @throws Exception if there is an error.
     */
    void createUserInterfaceForSystemLevelProvidedRole(String systemLevelProvidedRoleName, String interfaceName, String providedComponentInstanceName, String providedRoleNameOfComponentInstance, UserInterfaceType userInterfaceType) throws Exception;

    /**
     * Create a user interface for a system-level sink role.
     *
     * @param systemLevelSinkRoleName         the system-level sink role name.
     * @param eventGroupName                  the event group name.
     * @param sinkComponentInstanceName       the sink component instance name.
     * @param sinkRoleNameOfComponentInstance the sink role name of the component instance.
     * @param userInterfaceType               the given user interface type.
     * @throws Exception if there is an error.
     */
    void createUserInterfaceForSystemLevelSinkRole(String systemLevelSinkRoleName, String eventGroupName, String sinkComponentInstanceName, String sinkRoleNameOfComponentInstance, UserInterfaceType userInterfaceType) throws Exception;


    /**
     * Stop the container.
     */
    void stop();
}
